home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 25 / Cream of the Crop 25.iso / program / tcpdumpb.zip / print-decnet.c < prev    next >
C/C++ Source or Header  |  1996-07-23  |  22KB  |  776 lines

  1. /*
  2.  * Copyright (c) 1992, 1993, 1994, 1995, 1996
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  */
  21.  
  22. #ifndef lint
  23. static char rcsid[] =
  24.     "@(#) $Header: print-decnet.c,v 1.22 96/07/23 14:17:22 leres Exp $ (LBL)";
  25. #endif
  26.  
  27. #include <sys/param.h>
  28. #include <sys/time.h>
  29. #include <sys/socket.h>
  30.  
  31. #if __STDC__
  32. struct mbuf;
  33. struct rtentry;
  34. #endif
  35. #include <net/if.h>
  36.  
  37. #ifdef    HAVE_LIBDNET
  38. #include <netdnet/dnetdb.h>
  39. #endif
  40.  
  41. #include <ctype.h>
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45. #include <unistd.h>
  46.  
  47. #include "decnet.h"
  48. #include "extract.h"
  49. #include "interface.h"
  50. #include "addrtoname.h"
  51.  
  52. /* Forwards */
  53. static void print_decnet_ctlmsg(const union routehdr *, u_int);
  54. static void print_t_info(int);
  55. static void print_l1_routes(const char *, u_int);
  56. static void print_l2_routes(const char *, u_int);
  57. static void print_i_info(int);
  58. static void print_elist(const char *, u_int);
  59. static void print_nsp(const u_char *, u_int);
  60. static void print_reason(int);
  61. #ifdef    PRINT_NSPDATA
  62. static void pdata(u_char *, int);
  63. #endif
  64.  
  65. #ifdef    HAVE_LIBDNET
  66. extern char *dnet_htoa(struct dn_naddr *);
  67. #endif
  68.  
  69. void
  70. decnet_print(register const u_char *ap, register u_int length,
  71.          register u_int caplen)
  72. {
  73.     static union routehdr rhcopy;
  74.     register union routehdr *rhp = &rhcopy;
  75.     register int mflags;
  76.     int dst, src, hops;
  77.     u_int rhlen, nsplen, pktlen;
  78.     const u_char *nspp;
  79.  
  80.     if (length < sizeof(struct shorthdr)) {
  81.         (void)printf("[|decnet]");
  82.         return;
  83.     }
  84.  
  85.     pktlen = EXTRACT_LE_16BITS(ap);
  86.  
  87.     rhlen = min(length, caplen);
  88.     rhlen = min(rhlen, sizeof(*rhp));
  89.     memcpy((char *)rhp, (char *)&(ap[sizeof(short)]), rhlen);
  90.  
  91.     mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
  92.  
  93.     if (mflags & RMF_PAD) {
  94.         /* pad bytes of some sort in front of message */
  95.         u_int padlen = mflags & RMF_PADMASK;
  96.         if (vflag)
  97.         (void) printf("[pad:%d] ", padlen);
  98.         ap += padlen;
  99.         length -= padlen;
  100.         caplen -= padlen;
  101.         rhlen = min(length, caplen);
  102.         rhlen = min(rhlen, sizeof(*rhp));
  103.         memcpy((char *)rhp, (char *)&(ap[sizeof(short)]), rhlen);
  104.         mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
  105.     }
  106.  
  107.     if (mflags & RMF_FVER) {
  108.         (void) printf("future-version-decnet");
  109.         default_print(ap, length);
  110.         return;
  111.     }
  112.  
  113.     /* is it a control message? */
  114.     if (mflags & RMF_CTLMSG) {
  115.         print_decnet_ctlmsg(rhp, min(length, caplen));
  116.         return;
  117.     }
  118.  
  119.     switch (mflags & RMF_MASK) {
  120.     case RMF_LONG:
  121.         dst =
  122.         EXTRACT_LE_16BITS(rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr);
  123.         src =
  124.         EXTRACT_LE_16BITS(rhp->rh_long.lg_src.dne_remote.dne_nodeaddr);
  125.         hops = EXTRACT_LE_8BITS(rhp->rh_long.lg_visits);
  126.         nspp = &(ap[sizeof(short) + sizeof(struct longhdr)]);
  127.         nsplen = min((length - sizeof(struct longhdr)),
  128.              (caplen - sizeof(struct longhdr)));
  129.         break;
  130.     case RMF_SHORT:
  131.         dst = EXTRACT_LE_16BITS(rhp->rh_short.sh_dst);
  132.         src = EXTRACT_LE_16BITS(rhp->rh_short.sh_src);
  133.         hops = (EXTRACT_LE_8BITS(rhp->rh_short.sh_visits) & VIS_MASK)+1;
  134.         nspp = &(ap[sizeof(short) + sizeof(struct shorthdr)]);
  135.         nsplen = min((length - sizeof(struct shorthdr)),
  136.              (caplen - sizeof(struct shorthdr)));
  137.         break;
  138.     default:
  139.         (void) printf("unknown message flags under mask");
  140.         default_print((u_char *)ap, length);
  141.         return;
  142.     }
  143.  
  144.     (void)printf("%s > %s %d ",
  145.             dnaddr_string(src), dnaddr_string(dst), pktlen);
  146.     if (vflag) {
  147.         if (mflags & RMF_RQR)
  148.         (void)printf("RQR ");
  149.         if (mflags & RMF_RTS)
  150.         (void)printf("RTS ");
  151.         if (mflags & RMF_IE)
  152.         (void)printf("IE ");
  153.         (void)printf("%d hops ", hops);
  154.     }
  155.  
  156.     print_nsp(nspp, nsplen);
  157. }
  158.  
  159. static void
  160. print_decnet_ctlmsg(register const union routehdr *rhp, u_int length)
  161. {
  162.     int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
  163.     register union controlmsg *cmp = (union controlmsg *)rhp;
  164.     int src, dst, info, blksize, eco, ueco, hello, other, vers;
  165.     etheraddr srcea, rtea;
  166.     int priority;
  167.     char *rhpx = (char *)rhp;
  168.  
  169.     switch (mflags & RMF_CTLMASK) {
  170.     case RMF_INIT:
  171.         (void)printf("init ");
  172.         src = EXTRACT_LE_16BITS(cmp->cm_init.in_src);
  173.         info = EXTRACT_LE_8BITS(cmp->cm_init.in_info);
  174.         blksize = EXTRACT_LE_16BITS(cmp->cm_init.in_blksize);
  175.         vers = EXTRACT_LE_8BITS(cmp->cm_init.in_vers);
  176.         eco = EXTRACT_LE_8BITS(cmp->cm_init.in_eco);
  177.         ueco = EXTRACT_LE_8BITS(cmp->cm_init.in_ueco);
  178.         hello = EXTRACT_LE_16BITS(cmp->cm_init.in_hello);
  179.         print_t_info(info);
  180.         (void)printf(
  181.         "src %sblksize %d vers %d eco %d ueco %d hello %d",
  182.             dnaddr_string(src), blksize, vers, eco, ueco,
  183.             hello);
  184.         break;
  185.     case RMF_VER:
  186.         (void)printf("verification ");
  187.         src = EXTRACT_LE_16BITS(cmp->cm_ver.ve_src);
  188.         other = EXTRACT_LE_8BITS(cmp->cm_ver.ve_fcnval);
  189.         (void)printf("src %s fcnval %o", dnaddr_string(src), other);
  190.         break;
  191.     case RMF_TEST:
  192.         (void)printf("test ");
  193.         src = EXTRACT_LE_16BITS(cmp->cm_test.te_src);
  194.         other = EXTRACT_LE_8BITS(cmp->cm_test.te_data);
  195.         (void)printf("src %s data %o", dnaddr_string(src), other);
  196.         break;
  197.     case RMF_L1ROUT:
  198.         (void)printf("lev-1-routing ");
  199.         src = EXTRACT_LE_16BITS(cmp->cm_l1rou.r1_src);
  200.         (void)printf("src %s ", dnaddr_string(src));
  201.         print_l1_routes(&(rhpx[sizeof(struct l1rout)]),
  202.                 length - sizeof(struct l1rout));
  203.         break;
  204.     case RMF_L2ROUT:
  205.         (void)printf("lev-2-routing ");
  206.         src = EXTRACT_LE_16BITS(cmp->cm_l2rout.r2_src);
  207.         (void)printf("src %s ", dnaddr_string(src));
  208.         print_l2_routes(&(rhpx[sizeof(struct l2rout)]),
  209.                 length - sizeof(struct l2rout));
  210.         break;
  211.     case RMF_RHELLO:
  212.         (void)printf("router-hello ");
  213.         vers = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_vers);
  214.         eco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_eco);
  215.         ueco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_ueco);
  216.         memcpy((char *)&srcea, (char *)&(cmp->cm_rhello.rh_src),
  217.         sizeof(srcea));
  218.         src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr);
  219.         info = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_info);
  220.         blksize = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_blksize);
  221.         priority = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_priority);
  222.         hello = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_hello);
  223.         print_i_info(info);
  224.         (void)printf(
  225.         "vers %d eco %d ueco %d src %s blksize %d pri %d hello %d",
  226.             vers, eco, ueco, dnaddr_string(src),
  227.             blksize, priority, hello);
  228.         print_elist(&(rhpx[sizeof(struct rhellomsg)]),
  229.                 length - sizeof(struct rhellomsg));
  230.         break;
  231.     case RMF_EHELLO:
  232.         (void)printf("endnode-hello ");
  233.         vers = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_vers);
  234.         eco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_eco);
  235.         ueco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_ueco);
  236.         memcpy((char *)&srcea, (char *)&(cmp->cm_ehello.eh_src),
  237.         sizeof(srcea));
  238.         src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr);
  239.         info = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_info);
  240.         blksize = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_blksize);
  241.         /*seed*/
  242.         memcpy((char *)&rtea, (char *)&(cmp->cm_ehello.eh_router),
  243.         sizeof(rtea));
  244.         dst = EXTRACT_LE_16BITS(rtea.dne_remote.dne_nodeaddr);
  245.         hello = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_hello);
  246.         other = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_data);
  247.         print_i_info(info);
  248.         (void)printf(
  249.     "vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o",
  250.             vers, eco, ueco, dnaddr_string(src),
  251.             blksize, dnaddr_string(dst), hello, other);
  252.         break;
  253.  
  254.     default:
  255.         (void)printf("unknown control message");
  256.         default_print((u_char *)rhp, length);
  257.         break;
  258.     }
  259. }
  260.  
  261. static void
  262. print_t_info(int info)
  263. {
  264.     int ntype = info & 3;
  265.     switch (ntype) {
  266.     case 0: (void)printf("reserved-ntype? "); break;
  267.     case TI_L2ROUT: (void)printf("l2rout "); break;
  268.     case TI_L1ROUT: (void)printf("l1rout "); break;
  269.     case TI_ENDNODE: (void)printf("endnode "); break;
  270.     }
  271.     if (info & TI_VERIF)
  272.         (void)printf("verif ");
  273.     if (info & TI_BLOCK)
  274.         (void)printf("blo ");
  275. }
  276.  
  277. static void
  278. print_l1_routes(const char *rp, u_int len)
  279. {
  280.     int count;
  281.     int id;
  282.     int info;
  283.  
  284.     /* The last short is a checksum */
  285.     while (len > (3 * sizeof(short))) {
  286.         count = EXTRACT_LE_16BITS(rp);
  287.         if (count > 1024)
  288.         return;    /* seems to be bogus from here on */
  289.         rp += sizeof(short);
  290.         len -= sizeof(short);
  291.         id = EXTRACT_LE_16BITS(rp);
  292.         rp += sizeof(short);
  293.         len -= sizeof(short);
  294.         info = EXTRACT_LE_16BITS(rp);
  295.         rp += sizeof(short);
  296.         len -= sizeof(short);
  297.         (void)printf("{ids %d-%d cost %d hops %d} ", id, id + count,
  298.                 RI_COST(info), RI_HOPS(info));
  299.     }
  300. }
  301.  
  302. static void
  303. print_l2_routes(const char *rp, u_int len)
  304. {
  305.     int count;
  306.     int area;
  307.     int info;
  308.  
  309.     /* The last short is a checksum */
  310.     while (len > (3 * sizeof(short))) {
  311.         count = EXTRACT_LE_16BITS(rp);
  312.         if (count > 1024)
  313.         return;    /* seems to be bogus from here on */
  314.         rp += sizeof(short);
  315.         len -= sizeof(short);
  316.         area = EXTRACT_LE_16BITS(rp);
  317.         rp += sizeof(short);
  318.         len -= sizeof(short);
  319.         info = EXTRACT_LE_16BITS(rp);
  320.         rp += sizeof(short);
  321.         len -= sizeof(short);
  322.         (void)printf("{areas %d-%d cost %d hops %d} ", area, area + count,
  323.                 RI_COST(info), RI_HOPS(info));
  324.     }
  325. }
  326.  
  327. static void
  328. print_i_info(int info)
  329. {
  330.     int ntype = info & II_TYPEMASK;
  331.     switch (ntype) {
  332.     case 0: (void)printf("reserved-ntype? "); break;
  333.     case II_L2ROUT: (void)printf("l2rout "); break;
  334.     case II_L1ROUT: (void)printf("l1rout "); break;
  335.     case II_ENDNODE: (void)printf("endnode "); break;
  336.     }
  337.     if (info & II_VERIF)
  338.         (void)printf("verif ");
  339.     if (info & II_NOMCAST)
  340.         (void)printf("nomcast ");
  341.     if (info & II_BLOCK)
  342.         (void)printf("blo ");
  343. }
  344.  
  345. static void
  346. print_elist(const char *elp, u_int len)
  347. {
  348.     /* Not enough examples available for me to debug this */
  349. }
  350.  
  351. static void
  352. print_nsp(const u_char *nspp, u_int nsplen)
  353. {
  354.     const struct nsphdr *nsphp = (struct nsphdr *)nspp;
  355.     int dst, src, flags;
  356.  
  357.     flags = EXTRACT_LE_8BITS(nsphp->nh_flags);
  358.     dst = EXTRACT_LE_16BITS(nsphp->nh_dst);
  359.     src = EXTRACT_LE_16BITS(nsphp->nh_src);
  360.  
  361.     switch (flags & NSP_TYPEMASK) {
  362.     case MFT_DATA:
  363.         switch (flags & NSP_SUBMASK) {
  364.         case MFS_BOM:
  365.         case MFS_MOM:
  366.         case MFS_EOM:
  367.         case MFS_BOM+MFS_EOM:
  368.         printf("data %d>%d ", src, dst);
  369.         {
  370.             struct seghdr *shp = (struct seghdr *)nspp;
  371.             int ack;
  372. #ifdef    PRINT_NSPDATA
  373.             u_char *dp;
  374. #endif
  375.             u_int data_off = sizeof(struct minseghdr);
  376.  
  377.             ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
  378.             if (ack & SGQ_ACK) {    /* acknum field */
  379.             if ((ack & SGQ_NAK) == SGQ_NAK)
  380.                 (void)printf("nak %d ", ack & SGQ_MASK);
  381.             else
  382.                 (void)printf("ack %d ", ack & SGQ_MASK);
  383.                 ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
  384.             data_off += sizeof(short);
  385.             if (ack & SGQ_OACK) {    /* ackoth field */
  386.                 if ((ack & SGQ_ONAK) == SGQ_ONAK)
  387.                 (void)printf("onak %d ", ack & SGQ_MASK);
  388.                 else
  389.                 (void)printf("oack %d ", ack & SGQ_MASK);
  390.                 ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
  391.                 data_off += sizeof(short);
  392.             }
  393.             }
  394.             (void)printf("seg %d ", ack & SGQ_MASK);
  395. #ifdef    PRINT_NSPDATA
  396.             dp = &(nspp[data_off]);
  397.             pdata(dp, 10);
  398. #endif
  399.         }
  400.         break;
  401.         case MFS_ILS+MFS_INT:
  402.         printf("intr ");
  403.         {
  404.             struct seghdr *shp = (struct seghdr *)nspp;
  405.             int ack;
  406. #ifdef    PRINT_NSPDATA
  407.             u_char *dp;
  408. #endif
  409.             u_int data_off = sizeof(struct minseghdr);
  410.  
  411.             ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
  412.             if (ack & SGQ_ACK) {    /* acknum field */
  413.             if ((ack & SGQ_NAK) == SGQ_NAK)
  414.                 (void)printf("nak %d ", ack & SGQ_MASK);
  415.             else
  416.                 (void)printf("ack %d ", ack & SGQ_MASK);
  417.                 ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
  418.             data_off += sizeof(short);
  419.             if (ack & SGQ_OACK) {    /* ackdat field */
  420.                 if ((ack & SGQ_ONAK) == SGQ_ONAK)
  421.                 (void)printf("nakdat %d ", ack & SGQ_MASK);
  422.                 else
  423.                 (void)printf("ackdat %d ", ack & SGQ_MASK);
  424.                 ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
  425.                 data_off += sizeof(short);
  426.             }
  427.             }
  428.             (void)printf("seg %d ", ack & SGQ_MASK);
  429. #ifdef    PRINT_NSPDATA
  430.             dp = &(nspp[data_off]);
  431.             pdata(dp, 10);
  432. #endif
  433.         }
  434.         break;
  435.         case MFS_ILS:
  436.         (void)printf("link-service %d>%d ", src, dst);
  437.         {
  438.             struct seghdr *shp = (struct seghdr *)nspp;
  439.             struct lsmsg *lsmp =
  440.             (struct lsmsg *)&(nspp[sizeof(struct seghdr)]);
  441.             int ack;
  442.             int lsflags, fcval;
  443.  
  444.             ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
  445.             if (ack & SGQ_ACK) {    /* acknum field */
  446.             if ((ack & SGQ_NAK) == SGQ_NAK)
  447.                 (void)printf("nak %d ", ack & SGQ_MASK);
  448.             else
  449.                 (void)printf("ack %d ", ack & SGQ_MASK);
  450.                 ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
  451.             if (ack & SGQ_OACK) {    /* ackdat field */
  452.                 if ((ack & SGQ_ONAK) == SGQ_ONAK)
  453.                 (void)printf("nakdat %d ", ack & SGQ_MASK);
  454.                 else
  455.                 (void)printf("ackdat %d ", ack & SGQ_MASK);
  456.                 ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
  457.             }
  458.             }
  459.             (void)printf("seg %d ", ack & SGQ_MASK);
  460.             lsflags = EXTRACT_LE_8BITS(lsmp->ls_lsflags);
  461.             fcval = EXTRACT_LE_8BITS(lsmp->ls_fcval);
  462.             switch (lsflags & LSI_MASK) {
  463.             case LSI_DATA:
  464.             (void)printf("dat seg count %d ", fcval);
  465.             switch (lsflags & LSM_MASK) {
  466.             case LSM_NOCHANGE:
  467.                 break;
  468.             case LSM_DONOTSEND:
  469.                 (void)printf("donotsend-data ");
  470.                 break;
  471.             case LSM_SEND:
  472.                 (void)printf("send-data ");
  473.                 break;
  474.             default:
  475.                 (void)printf("reserved-fcmod? %x", lsflags);
  476.                 break;
  477.             }
  478.             break;
  479.             case LSI_INTR:
  480.             (void)printf("intr req count %d ", fcval);
  481.             break;
  482.             default:
  483.             (void)printf("reserved-fcval-int? %x", lsflags);
  484.             break;
  485.             }
  486.         }
  487.         break;
  488.         default:
  489.         (void)printf("reserved-subtype? %x %d > %d", flags, src, dst);
  490.         break;
  491.         }
  492.         break;
  493.     case MFT_ACK:
  494.         switch (flags & NSP_SUBMASK) {
  495.         case MFS_DACK:
  496.         (void)printf("data-ack %d>%d ", src, dst);
  497.         {
  498.             struct ackmsg *amp = (struct ackmsg *)nspp;
  499.             int ack;
  500.  
  501.             ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]);
  502.             if (ack & SGQ_ACK) {    /* acknum field */
  503.             if ((ack & SGQ_NAK) == SGQ_NAK)
  504.                 (void)printf("nak %d ", ack & SGQ_MASK);
  505.             else
  506.                 (void)printf("ack %d ", ack & SGQ_MASK);
  507.                 ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]);
  508.             if (ack & SGQ_OACK) {    /* ackoth field */
  509.                 if ((ack & SGQ_ONAK) == SGQ_ONAK)
  510.                 (void)printf("onak %d ", ack & SGQ_MASK);
  511.                 else
  512.                 (void)printf("oack %d ", ack & SGQ_MASK);
  513.             }
  514.             }
  515.         }
  516.         break;
  517.         case MFS_IACK:
  518.         (void)printf("ils-ack %d>%d ", src, dst);
  519.         {
  520.             struct ackmsg *amp = (struct ackmsg *)nspp;
  521.             int ack;
  522.  
  523.             ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]);
  524.             if (ack & SGQ_ACK) {    /* acknum field */
  525.             if ((ack & SGQ_NAK) == SGQ_NAK)
  526.                 (void)printf("nak %d ", ack & SGQ_MASK);
  527.             else
  528.                 (void)printf("ack %d ", ack & SGQ_MASK);
  529.                 ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]);
  530.             if (ack & SGQ_OACK) {    /* ackdat field */
  531.                 if ((ack & SGQ_ONAK) == SGQ_ONAK)
  532.                 (void)printf("nakdat %d ", ack & SGQ_MASK);
  533.                 else
  534.                 (void)printf("ackdat %d ", ack & SGQ_MASK);
  535.             }
  536.             }
  537.         }
  538.         break;
  539.         case MFS_CACK:
  540.         (void)printf("conn-ack %d", dst);
  541.         break;
  542.         default:
  543.         (void)printf("reserved-acktype? %x %d > %d", flags, src, dst);
  544.         break;
  545.         }
  546.         break;
  547.     case MFT_CTL:
  548.         switch (flags & NSP_SUBMASK) {
  549.         case MFS_CI:
  550.         case MFS_RCI:
  551.         if ((flags & NSP_SUBMASK) == MFS_CI)
  552.             (void)printf("conn-initiate ");
  553.         else
  554.             (void)printf("retrans-conn-initiate ");
  555.         (void)printf("%d>%d ", src, dst);
  556.         {
  557.             struct cimsg *cimp = (struct cimsg *)nspp;
  558.             int services, info, segsize;
  559. #ifdef    PRINT_NSPDATA
  560.             u_char *dp;
  561. #endif
  562.  
  563.             services = EXTRACT_LE_8BITS(cimp->ci_services);
  564.             info = EXTRACT_LE_8BITS(cimp->ci_info);
  565.             segsize = EXTRACT_LE_16BITS(cimp->ci_segsize);
  566.  
  567.             switch (services & COS_MASK) {
  568.             case COS_NONE:
  569.             break;
  570.             case COS_SEGMENT:
  571.             (void)printf("seg ");
  572.             break;
  573.             case COS_MESSAGE:
  574.             (void)printf("msg ");
  575.             break;
  576.             case COS_CRYPTSER:
  577.             (void)printf("crypt ");
  578.             break;
  579.             }
  580.             switch (info & COI_MASK) {
  581.             case COI_32:
  582.             (void)printf("ver 3.2 ");
  583.             break;
  584.             case COI_31:
  585.             (void)printf("ver 3.1 ");
  586.             break;
  587.             case COI_40:
  588.             (void)printf("ver 4.0 ");
  589.             break;
  590.             case COI_41:
  591.             (void)printf("ver 4.1 ");
  592.             break;
  593.             }
  594.             (void)printf("segsize %d ", segsize);
  595. #ifdef    PRINT_NSPDATA
  596.             dp = &(nspp[sizeof(struct cimsg)]);
  597.             pdata(dp, nsplen - sizeof(struct cimsg));
  598. #endif
  599.         }
  600.         break;
  601.         case MFS_CC:
  602.         (void)printf("conn-confirm %d>%d ", src, dst);
  603.         {
  604.             struct ccmsg *ccmp = (struct ccmsg *)nspp;
  605.             int services, info;
  606.             u_int segsize, optlen;
  607. #ifdef    PRINT_NSPDATA
  608.             u_char *dp;
  609. #endif
  610.  
  611.             services = EXTRACT_LE_8BITS(ccmp->cc_services);
  612.             info = EXTRACT_LE_8BITS(ccmp->cc_info);
  613.             segsize = EXTRACT_LE_16BITS(ccmp->cc_segsize);
  614.             optlen = EXTRACT_LE_8BITS(ccmp->cc_optlen);
  615.  
  616.             switch (services & COS_MASK) {
  617.             case COS_NONE:
  618.             break;
  619.             case COS_SEGMENT:
  620.             (void)printf("seg ");
  621.             break;
  622.             case COS_MESSAGE:
  623.             (void)printf("msg ");
  624.             break;
  625.             case COS_CRYPTSER:
  626.             (void)printf("crypt ");
  627.             break;
  628.             }
  629.             switch (info & COI_MASK) {
  630.             case COI_32:
  631.             (void)printf("ver 3.2 ");
  632.             break;
  633.             case COI_31:
  634.             (void)printf("ver 3.1 ");
  635.             break;
  636.             case COI_40:
  637.             (void)printf("ver 4.0 ");
  638.             break;
  639.             case COI_41:
  640.             (void)printf("ver 4.1 ");
  641.             break;
  642.             }
  643.             (void)printf("segsize %d ", segsize);
  644.             if (optlen) {
  645.             (void)printf("optlen %d ", optlen);
  646. #ifdef    PRINT_NSPDATA
  647.             optlen = min(optlen, nsplen - sizeof(struct ccmsg));
  648.             dp = &(nspp[sizeof(struct ccmsg)]);
  649.             pdata(dp, optlen);
  650. #endif
  651.             }
  652.         }
  653.         break;
  654.         case MFS_DI:
  655.         (void)printf("disconn-initiate %d>%d ", src, dst);
  656.         {
  657.             struct dimsg *dimp = (struct dimsg *)nspp;
  658.             int reason;
  659.             u_int optlen;
  660. #ifdef    PRINT_NSPDATA
  661.             u_char *dp;
  662. #endif
  663.  
  664.             reason = EXTRACT_LE_16BITS(dimp->di_reason);
  665.             optlen = EXTRACT_LE_8BITS(dimp->di_optlen);
  666.  
  667.             print_reason(reason);
  668.             if (optlen) {
  669.             (void)printf("optlen %d ", optlen);
  670. #ifdef    PRINT_NSPDATA
  671.             optlen = min(optlen, nsplen - sizeof(struct dimsg));
  672.             dp = &(nspp[sizeof(struct dimsg)]);
  673.             pdata(dp, optlen);
  674. #endif
  675.             }
  676.         }
  677.         break;
  678.         case MFS_DC:
  679.         (void)printf("disconn-confirm %d>%d ", src, dst);
  680.         {
  681.             struct dcmsg *dcmp = (struct dcmsg *)nspp;
  682.             int reason;
  683.  
  684.             reason = EXTRACT_LE_16BITS(dcmp->dc_reason);
  685.  
  686.             print_reason(reason);
  687.         }
  688.         break;
  689.         default:
  690.         (void)printf("reserved-ctltype? %x %d > %d", flags, src, dst);
  691.         break;
  692.         }
  693.         break;
  694.     default:
  695.         (void)printf("reserved-type? %x %d > %d", flags, src, dst);
  696.         break;
  697.     }
  698. }
  699.  
  700. static struct tok reason2str[] = {
  701.     { UC_OBJREJECT,        "object rejected connect" },
  702.     { UC_RESOURCES,        "insufficient resources" },
  703.     { UC_NOSUCHNODE,    "unrecognized node name" },
  704.     { DI_SHUT,        "node is shutting down" },
  705.     { UC_NOSUCHOBJ,        "unrecognized object" },
  706.     { UC_INVOBJFORMAT,    "invalid object name format" },
  707.     { UC_OBJTOOBUSY,    "object too busy" },
  708.     { DI_PROTOCOL,        "protocol error discovered" },
  709.     { DI_TPA,        "third party abort" },
  710.     { UC_USERABORT,        "user abort" },
  711.     { UC_INVNODEFORMAT,    "invalid node name format" },
  712.     { UC_LOCALSHUT,        "local node shutting down" },
  713.     { DI_LOCALRESRC,    "insufficient local resources" },
  714.     { DI_REMUSERRESRC,    "insufficient remote user resources" },
  715.     { UC_ACCESSREJECT,    "invalid access control information" },
  716.     { DI_BADACCNT,        "bad ACCOUNT information" },
  717.     { UC_NORESPONSE,    "no response from object" },
  718.     { UC_UNREACHABLE,    "node unreachable" },
  719.     { DC_NOLINK,        "no link terminate" },
  720.     { DC_COMPLETE,        "disconnect complete" },
  721.     { DI_BADIMAGE,        "bad image data in connect" },
  722.     { DI_SERVMISMATCH,    "cryptographic service mismatch" },
  723.     { 0,            NULL }
  724. };
  725.  
  726. static void
  727. print_reason(register int reason)
  728. {
  729.     printf("%s ", tok2str(reason2str, "reason-%d", reason));
  730. }
  731.  
  732. char *
  733. dnnum_string(u_short dnaddr)
  734. {
  735.     char *str;
  736.     int area = (dnaddr & AREAMASK) >> AREASHIFT;
  737.     int node = dnaddr & NODEMASK;
  738.  
  739.     str = (char *)malloc(sizeof("00.0000"));
  740.     if (str == NULL)
  741.         error("dnnum_string: malloc");
  742.     sprintf(str, "%d.%d", area, node);
  743.     return(str);
  744. }
  745.  
  746. char *
  747. dnname_string(u_short dnaddr)
  748. {
  749. #ifdef    HAVE_LIBDNET
  750.     struct dn_naddr dna;
  751.  
  752.     dna.a_len = sizeof(short);
  753.     memcpy((char *)dna.a_addr, (char *)&dnaddr, sizeof(short));
  754.     return (savestr(dnet_htoa(&dna)));
  755. #else
  756.     return(dnnum_string(dnaddr));    /* punt */
  757. #endif
  758. }
  759.  
  760. #ifdef    PRINT_NSPDATA
  761. static void
  762. pdata(u_char *dp, u_int maxlen)
  763. {
  764.     char c;
  765.     u_int x = maxlen;
  766.  
  767.     while (x-- > 0) {
  768.         c = *dp++;
  769.         if (isprint(c))
  770.         putchar(c);
  771.         else
  772.         printf("\\%o", c & 0xFF);
  773.     }
  774. }
  775. #endif
  776.